package mainpkg

import (
    "appengine"
    mail "gae/mail"
    "http"
//    "template"
//    "time"
    "fmt"
    "os"
//    "log"
	"strings"
	"json"
//	"bytes"
//	"bufio"
	//"mail"
//	"io/ioutil"
//	"io"
)

const URL_MAIL_PREFIX = "/_ah/mail/"

func init() {
//    http.Handle("/", http.FileServer("/home/antonio/mm/goAppEngine/myApp/", ""))
//    http.HandleFunc("/", main)
//    http.HandleFunc("/stockwatcher/stockPrices", rpcJson)
    http.HandleFunc("/processJSON", processJSON)
    http.HandleFunc(URL_MAIL_PREFIX, incomingMail)
}


func incomingMail(w http.ResponseWriter, r *http.Request) {
        c := appengine.NewContext(r)
        receiver := r.URL.Path[len(URL_MAIL_PREFIX):]
        if idx := strings.Index( receiver, "@") ; idx > -1 {
	        receiver = receiver[:idx]
        }
        c.Debugf("Received mail for %v", receiver)

        
        switch receiver {
/*
        	case "list": 
				myMail, err := mail.NewMail( r.Body)
				if err != nil {
			        c.Debugf( "Error processing mail: %v", err)
			        return
			    }
			    r.Body.Close()
        		MailListOptions( c, myMail)
*/        	//case "grumo-jueves": mailGrumoJueves( c, myMail)
        	case "echo": 
        		MailEcho( c, r.Body)
			    r.Body.Close()
        	default: 
        		group, err := getAddresses(c,&receiver) 
				c.Debugf( "mail-to:%v", *group)
        		if err != nil {
        			c.Debugf( "Error %v", err)
        			return
        		}
				myMail, err := mail.NewMail( r.Body)
				if err != nil {
			        c.Debugf( "Error processing mail: %v", err)
			        return
			    }
			    r.Body.Close()
        		mail.SendMail( c, myMail)
        }
        c.Debugf("One last try!")
}


type stock struct {
	symbol string
	price float32
	change float32
}

func (s stock) MarshalJSON() ([]byte, os.Error) {
	return []byte( fmt.Sprintf( `{"symbol": "%s", "price": %v, "change": %v} `, s.symbol, s.price, s.change) ), nil
}




//updateGroup {'grumo-test', ['antonio.diaz.gil@gmail.com', 'magius.varios@gmail.com']}
//processJSON?cmd={"UpdateGroup":{"Name":"grumo-test","Addresses":["antonio.diaz.gil@gmail.com","magius.varios@gmail.com"]}}
type JsonMessage struct {
	UpdateGroup *GroupAddress
	QueryGroup *string
	QueryGroups *string
}



func processJSON(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	jsonIn := r.FormValue("cmd")
	c.Debugf( "JSON Request: %v", jsonIn)

	var message JsonMessage
	err := json.Unmarshal(([]uint8)(jsonIn), &message)
	if err != nil {
        http.Error(w, err.String(), http.StatusInternalServerError)
	}
	c.Debugf( "jsonIn:%v", message)
	if message.UpdateGroup != nil {
		cmdUpdateGroup(w,r,c,message)
	} else if message.QueryGroup != nil {
		cmdQueryGroup(w,r,c,message)
	} else if message.QueryGroups != nil {
		cmdQueryGroups(w,r,c,message)
	}
}

type JsonResponse struct {
	Code int32
	Desc string
}

func cmdUpdateGroup(w http.ResponseWriter, r *http.Request, c appengine.Context, message JsonMessage) {
	//message.UpdateGroup = &Group{"grumo-test", []string{"antonio.diaz.gil@gmail.com", "magius.varios@gmail.com"}}
	//jsonOutAux, err := json.Marshal(message)
	//c.Debugf( "jsonOut1:%v", string(jsonOutAux))
	//cmd={"UpdateGroup":{"Name":"grumo-jueves","Addresses":["antonio.diaz.gil@gmail.com","magius.varios@gmail.com"]}}
	//http://neuronpile.appspot.com/processJSON?cmd={%22UpdateGroup%22:{%22Name%22:%22grumo-jueves%22,%22Addresses%22:[%22Jose%20Cortes%20%3Cfjosecortes@gmail.com%3E%22,%22Fernando%20Benito%20%3Cferbenval@gmail.com%3E%22,%22Pilar%20Ayuso%20%3Cpilar.ayuso@isftic.mepsyd.es%3E%22,%22Cristina%20Moreno%20Ruiz%20%3Ccristina_moreno_ruiz@yahoo.es%3E%22,%22antonio.diaz.gil@gmail.com%22]}}
	err := setAddresses(c, message.UpdateGroup)
	if err != nil {
        http.Error(w, err.String(), http.StatusInternalServerError)
        return
	}

	messageResponse := JsonResponse{ 0, "OK"}
	jsonOut, err := json.Marshal(messageResponse)
	if err != nil {
        http.Error(w, err.String(), http.StatusInternalServerError)
        return
	}
	c.Debugf( "jsonOut2:%v", string(jsonOut))
	fmt.Fprintf( w, "%v", string(jsonOut))
}

type JsonResponseGroup struct {
	Code int32
	Desc string
	addresses *GroupAddress
}
type JsonResponseGroups struct {
	Code int32
	Desc string
	Groups []Group
}

//http://localhost:8080/processJSON?cmd={%22QueryGroup%22:%22grumo-test%22}
//http://neuronpile.appspot.com/processJSON?cmd={%22UpdateGroup%22:{%22Name%22:%22grumo-test%22,%22Addresses%22:[%22magius.varios@gmail.com%22]}}
//http://neuronpile.appspot.com/processJSON?cmd={%22QueryGroup%22:%22grumo-test%22}
func cmdQueryGroup(w http.ResponseWriter, r *http.Request, c appengine.Context, message JsonMessage) {
c.Debugf( "message.QueryGroup:%v", *(message.QueryGroup))
	group, err := getAddresses(c, message.QueryGroup)
	if err != nil {
		c.Debugf( "err1:%v", err)
        http.Error(w, err.String(), http.StatusInternalServerError)
        return
	}

	messageResponse := JsonResponseGroup{ 0, "OK", group}
	jsonOut, err := json.Marshal(messageResponse)
	if err != nil {
		c.Debugf( "err2:%v", err)
        http.Error(w, err.String(), http.StatusInternalServerError)
        return
	}
	c.Debugf( "jsonOut2:%v", string(jsonOut))
	fmt.Fprintf( w, "%v", string(jsonOut))
}

func cmdQueryGroups(w http.ResponseWriter, r *http.Request, c appengine.Context, message JsonMessage) {
c.Debugf( "message.QueryGroup:%v", *(message.QueryGroups))
	groups, err := getGroups(c, message.QueryGroups)
	
	if err != nil {
		c.Debugf( "err1:%v", err)
        http.Error(w, err.String(), http.StatusInternalServerError)
        return
	}

/*
name := "grumo-test"
message.QueryGroup = &name
jsonOutAux, err := json.Marshal(message)
c.Debugf( "jsonOut1:%v", string(jsonOutAux))
*/
	messageResponse := JsonResponseGroups{ 0, "OK", groups}
//	messageResponse := &JsonResponseGroups { Code:0, Desc:"OK"}
	
	jsonOut, err := json.Marshal(messageResponse)
	if err != nil {
		c.Debugf( "err2:%v", err)
        http.Error(w, err.String(), http.StatusInternalServerError)
        return
	}
	jsonOut2 := fmt.Sprintf( "__gwt_jsonp__.P0.onSuccess(%s);", jsonOut)
//	jsonOut2 := string(jsonOut)
/*
jsonOut := `__gwt_jsonp__.P0.onSuccess([
  {
    "symbol": "ABC",
    "price": 96.204659543522,
    "change": -1.6047997669492
  },
  {
    "symbol": "DEF",
    "price": 61.929176899084,
    "change": 0.22809544419493
  }
]);`
*/
	c.Debugf( "jsonOut2:%v", jsonOut2)
	fmt.Fprintf( w, "%v", jsonOut2)
}